#include <iostream>
using namespace std;

const int N = 30010;
int T;
char op;
int a, b;
int p[N], d[N], Size[N]; //p维护并查集，d维护到父节点的距离，size仅仅对根节点生效，表示根结点后面有多少结点

int find(int x)
{
    if (x == p[x])         //如果我本生就是根结点
        return x;          //那直接返回我自己
    int root = find(p[x]); //不然就往上层去根结点
    d[x] += d[p[x]];       //x到父节点加上父节点到根节点的距离，这里注意，父节点已经接上根结点了
    //这一步也说明了为啥不能不能直接用根节点的d来装size，因为这样会导致最后长度会加上一整个原根节点的长度
    p[x] = root; //最后自己也认祖归宗
    return p[x];
}

int main()
{
    freopen("cin.txt", "r", stdin);
    cin >> T;
    for (int i = 1; i < N; ++i)
    {
        p[i] = i;    //初始化并查集
        Size[i] = 1; //现阶段每个集合都自己
        d[i] = 0;    //我到我自己，距离当然都是0
    }
    while (T--)
    {
        cin >> op >> a >> b;
        if (op == 'M') //如果要接上去
        {
            int pa = find(a), pb = find(b); //因为每次find都会改变顺序，而很多东西没维护好之前改变顺序是会出问题的，所以这里不能随便find
            if (pa == pb)
                ; //如果已经在同一列了
            else
            {
                d[pa] = Size[pb];     //a接在b后面嘛，所以pa就是一个子节点了，到根节点的距离就是b所在的队列的长度
                Size[pb] += Size[pa]; //然后长度也对续上嘛
                p[pa] = pb;           //然后认作父亲
            }
        }
        else //不然就是查询
        {
            int pa = find(a), pb = find(b);
            if (pa != pb)
                cout << -1 << endl; //不在一行直接过
            else if (a == b)
                cout << 0 << endl; //同一个距离直接为0
            else
                cout << abs(d[a] - d[b]) - 1 << endl;
        }
    }
    return 0;
}